﻿import mx.controls.ComboBox;
import mx.controls.NumericStepper;

import com.yourdomain.spreadshop.gui.GUI;
import com.yourdomain.spreadshop.gui.mod.lib.LoaderAnimation;
import com.yourdomain.spreadshop.gui.mod.lib.Module;

import flash.filters.DropShadowFilter;

import net.spreadshirt.logger.Logger;

/**
 * The ItemDetail class displays a single article item
 * and provides the "add to shopping cart" functionality
 * There are some thumbnail buttons which makes the user able
 * to switch various detail views of the product.
 */
class com.yourdomain.spreadshop.gui.mod.ItemDetail {

	// The reference to the swf file.
	private static var _SWF:String = "spreadshop_itemDetail.swf";

	// Various visual settings.
	private static var _POSITION:Object = { x: 498, y: 8 };
	private static var _LABEL_TITLE:String = "Produktansicht";
	private static var _LABEL_ORDER:String = "In den Warenkorb";
	private static var _LABEL_SIZE:String = "Größe: "
		+"<b><font color=\"#666666\">[size]</font></b>";
	private static var _LABEL_QUANTITY:String = "Menge: "
		+"<b><font color=\"#666666\">[quantity]</font></b>";
	private static var _TOOLTIP_ADDTOBASKET:String = ""
		+"Hier klicken, um den Artikel\n"
		+"zum Warenkorb hinzuzufügen!";
	private static var _THUMB_COLS:Number = 3;
	private static var _THUMB_DISTANCE_X:Number = 52;
	private static var _THUMB_DISTANCE_Y:Number = 52;

	// The reference to the GUI main class.
	private var _gui:GUI;

	// The movie clip container.
	private var _clip:MovieClip;

	// A variable that contains all article data.
	private var _article_id:Number;

	// Stores quantity, sizeID and the colorID.
	private var _quantity:Number;
	private var _producttype_size_id:Number;
	private var _producttype_color_id:Number;

	/**
	 * ItemDetail Constructor
	 */
	public function ItemDetail(
		gui:GUI,
		clip:MovieClip,
		level:Number
	) {
		// Connects with the GUI instance.
		_gui = gui;
		// Create a new movie clip and set it's position on stage.
		_clip = clip.createEmptyMovieClip("itemDetail", level);
		// Create a listener object to watch loading in progress.
		var mclListener:Object = new Object();
		mclListener.timer = [0, 0];
		mclListener.onLoadStart = function(target:MovieClip):Void {
		    this.timer[0] = getTimer();
			Logger.getLog().info("GUI - ItemDetail: start loading");
		};
		mclListener.onLoadComplete = function(target:MovieClip):Void {
			this.timer[1] = getTimer();
		};
		mclListener.itemsDetail = this;
		mclListener.onLoadInit = function(target:MovieClip):Void {
			var timer:Number = this.timer[1] - this.timer[0];
			var bytes:Number = target.getBytesLoaded();
			Logger.getLog().info("GUI - ItemDetail: "
				+ bytes +" Bytes loaded in "+ timer +" ms.");
			this.itemsDetail.setup();
		};
		// Create movie clip loader an attach the listener object.
		var mcLoader:MovieClipLoader = new MovieClipLoader();
		mcLoader.addListener(mclListener);
		mcLoader.loadClip(_gui.swf_path + _SWF, _clip);
	}

	/**
	 * Hides the module.
	 */
	public function hide():Void {
		_clip.itemDetail.hide();
	}

	/**
	 * Setup
	 */
	private function setup():Void {
		_gui.initModuleDone("initItemDetail");
		// Creates an alias to the item detail movie clip.
		var clip:MovieClip = _clip.itemDetail;
		// Setup modul.
		var module:Module = new Module(
			_gui,
			clip,
			false,
			_LABEL_TITLE,
			_POSITION.x,
			_POSITION.y
		);
		// Setup the filter effects.
	    var filShadow:DropShadowFilter = Module.FILTER_SUB_SHADOW;
	    var filArray:Array = new Array();
	    filArray.push(filShadow);
	    clip.item.base.filters = filArray;
	    clip.item.base.cacheAsBitmap = true;
	}

	/**
	 * Shows the item.
	 */
	 public function showItem(
	 	item:Object,
	 	item_producttype_size_id:Number,
	 	item_quantity:Number
	 ):Void {
	 	// Reset quantity to default value.
	 	_quantity = 1;
	 	// Remember the article ID.
		_article_id = item.article_id;
	 	// Remember the color ID of the producttype.
		_producttype_color_id = item.producttype_color_id;
		// Create an alias to the item detail movie clip.
		var detail:MovieClip = _clip.itemDetail;
	 	// Show the item detail movie clip.
	 	detail.setToFront();
	 	// Creates an alias to the item movie clip.
	 	var mc:MovieClip = detail.item;
		// Setup the item detail movie clip.
		mc.base.tooltip = _TOOLTIP_ADDTOBASKET;
		mc.base.itemsDetail = this;
		mc.base.onRollOver = function():Void {
			var hi:MovieClip = this._parent.hi;
			hi.isOver = true;
			hi.play();
			this.itemsDetail._gui.startTooltip(this.tooltip);
		};
		mc.base.onRollOut =
		mc.base.onDragOut = function():Void {
			var hi:MovieClip = this._parent.hi;
			hi.isOver = false;
			this.itemsDetail._gui.stopTooltip();
		};
		mc.base.onPress = function():Void {
			this.itemsDetail.addToBasket();
		};
		mc.info.name.tf.text = item.name;
		mc.info.description.tf.text = item.description;
		// Setup the info buttons.
		var infobts:MovieClip = detail.infobts;
		infobts.btshow.itemsDetail = this;
		infobts.btshow.onPress = function():Void {
			this.itemsDetail.setInfoMode(true);
		};
		infobts.bthide.onPress = function():Void {
			this.itemsDetail.setInfoMode(false);
		};
		// Hide the info movie clip.
		setInfoMode(false);
		// Show the gross.
		detail.gross.tf.text = transformGross(item.gross);
		// Show the currency.
		detail.currency.tf.text = item.currency;
		// Set the quantity.
		detail.strQuantity = _LABEL_QUANTITY;
		detail.setQuantity = function(quantity:Number):Void {
			this.quantity.tf.htmlText = this.strQuantity
				.split("[quantity]").join(quantity);
		};
		var nQuantity:Number = isNaN(item_quantity)
			? 1
			: item_quantity
		;
		detail.setQuantity(nQuantity);
		// Setup the sizes.
		detail.sizes = item.producttype_sizes.getAllItems();
		detail.strSize = _LABEL_SIZE;
		detail.setSize = function(size_id:Number):Void {
			var size:String;
			for(var s:Number = 0; s < this.sizes.length; s++) {
				if(this.sizes[s].producttype_size_id == size_id) {
					size = this.sizes[s].name;
					break;
				}
			}
			this.size.tf.htmlText = this.strSize.split("[size]").join(size);
		};
		// Set the quantity selector.
		var quantitySelector:NumericStepper = detail.quantitySelector;
		quantitySelector.tabEnabled = false;
		quantitySelector.minimum = 1;
		quantitySelector.maximum = 99;
		quantitySelector.value  = nQuantity;
		quantitySelector.setStyle("color", "0x0099ff");
		var quantitySelectorListener:Object = new Object();
		quantitySelectorListener.clip = detail;
		quantitySelectorListener.itemsDetail = this;
		quantitySelectorListener.change = function(evt:Object):Void {
			var n:Number = evt.target.value;
 			this.itemsDetail._quantity = n;
 			this.clip.setQuantity(n);
		};
		quantitySelector.addEventListener(
			"change",
			quantitySelectorListener
		);
		// Setup the sizes combobox.
		detail._lockroot = true;
		var sizeComboBox:ComboBox = detail.sizesSelector;
		sizeComboBox.tabEnabled = false;
		// Creates the data provider for the combo box.
		var dataProvider:Array = new Array();
		// Get and Sort the size items list.
		var sizesList:Array = item.producttype_sizes.getAllItems();
		sizesList.sortOn("weight", Array.NUMERIC);
		// Adds all sizes.
		for(var i:Number = 0; i < sizesList.length; i++) {
			dataProvider.push({
				data: sizesList[i].producttype_size_id,
				label: sizesList[i].name
			});
		}
		sizeComboBox.dataProvider = dataProvider;
		sizeComboBox.rowCount = dataProvider.length;
		var nSizeID:Number = isNaN(item_producttype_size_id)
			? dataProvider[0].data
			: item_producttype_size_id
		;
		detail.setSize(nSizeID);
		for(var s:Number = 0; s < dataProvider.length; s++) {
			if(dataProvider[s].data == nSizeID) {
				sizeComboBox.selectedIndex = s;
				break;
			}
		}
		sizeComboBox.setStyle("color", "0x0099ff");
		var sizeComboBoxListener:Object = new Object();
		sizeComboBoxListener.itemsDetail = this;
		sizeComboBoxListener.change = function(evt:Object):Void {
			var id:Number = evt.target.selectedItem.data;
			this.itemsDetail._producttype_size_id = id;
			evt.target._parent.setSize(id);

		};
		sizeComboBox.addEventListener("change", sizeComboBoxListener);
		var n:Number = sizeComboBox.selectedIndex;
		_producttype_size_id = dataProvider[n].data;
		// Setup the order button to add the item to the basket.
		var btorder:MovieClip = detail.btorder;
		btorder.label = _LABEL_ORDER;
		btorder.tabEnabled = false;
		btorder.itemsDetail = this;
		btorder.onPress = function():Void {
			this.itemsDetail.addToBasket();
		};
		// Setup thumbnail-image view.
		// Create list of thumbnail-image items.
		var thumbs:Array = new Array();
		for(var i:Number = 0; i < item.view_count; i++) {
			var id:Number = i + 1;
			var thumbItem:Object = {
				thumb_url: item.base_url +"&size=small&img_id="+ id,
				image_url: item.base_url +"&size=huge&img_id="+ id
			};
			thumbs.push(thumbItem);
		}
		for(var i:Number = 0; i < item.design_ids.length; i++) {
			var design_id:Number = parseInt(item.design_ids[i]);
			var design:Object = _gui.getDesignItem(design_id);
			var thumbItem:Object = {
				thumb_url: design.image_url,
				image_url: design.image_url
			};
			thumbs.push(thumbItem);
		}
		// Initialize the thumbnail-images.
		initThumbs(thumbs);
	}

	/**
	 * Show & hide the article information.
	 */
	private function setInfoMode(show:Boolean):Void {
	 	var infobts:MovieClip = _clip.itemDetail.infobts;
	 	var info:MovieClip = _clip.itemDetail.item.info;
		if(show) {
			infobts.btshow._visible = false;
			infobts.bthide._visible = true;
		} else {
			infobts.btshow._visible = true;
			infobts.bthide._visible = false;
		}
		info._visible = show;
	}

	/**
	 * Add item to the basket.
	 */
	private function addToBasket():Void {
		_gui.addBasketitem(
			_article_id,
			_quantity,
			_producttype_size_id,
			_producttype_color_id
		);
 	};

	/**
	 * Initialize thumbnail items
	 */
	private function initThumbs(items:Array):Void {
		// Create an alias to the thumbs movie clip.
		var thumbs:MovieClip = _clip.itemDetail.thumbs;
		// Remove all items.
		for(var i:String in thumbs) {
			if(typeof thumbs[i] == "movieclip"
				&& thumbs[i]._name != "item0"
			) {
				thumbs[i].removeMovieClip();
			}
		}
		// Create new thumbs.
		var row:Number = 0, col:Number = 0;
		for(var i:Number = 0; i < items.length; i++) {
			if(i > 0) {
				thumbs.item0.duplicateMovieClip("item"+ i, i);
			}
			var mc:MovieClip = thumbs["item"+ i];
			mc._x = _THUMB_DISTANCE_X * col++;
			mc._y = _THUMB_DISTANCE_Y * row;
			if(col % _THUMB_COLS == 0) {
				row++;
				col = 0;
			}
			// The items data.
			var item:Object = items[i];
			// Setup the thumbnail movie clip.
			mc.base.itemsDetail = this;
			mc.base.onRollOver = function():Void {
				var hi:MovieClip = this._parent.hi;
				hi.isOver = true;
				hi.play();
			};
			mc.base.onRollOut =
			mc.base.onDragOut = function():Void {
				var hi:MovieClip = this._parent.hi;
				hi.isOver = false;
			};
			mc.base.url = items[i].image_url;
			mc.base.onPress = function():Void {
				// Start loading the item detail picture.
				var clip:MovieClip = this._parent._parent._parent.item;
				var url:String = this.url;
				this.itemsDetail.loadItemPic(clip, url);
				// Hides the info view.
				this.itemsDetail.setInfoMode(false);
			};
			// Setup the filter effects.
		    var filShadow:DropShadowFilter = Module.FILTER_SUB_SHADOW;
		    var filArray:Array = new Array();
		    filArray.push(filShadow);
		    mc.base.filters = filArray;
			// Enable caching.
			mc.cacheAsBitmap = true;

			// Load picture.
			loadItemPic(mc, items[i].thumb_url);
		}
		// Select the first one.
		_clip.itemDetail.thumbs.item0.base.onPress();
	}

	/**
	 * Load item picture
	 */
	private function loadItemPic(clip:MovieClip, url:String):Void {
		// Setup loader clip.
		var loaderAni:LoaderAnimation = new LoaderAnimation(clip.loader);
		var mclListener:Object = new Object();
		mclListener.loader = loaderAni;
		mclListener.onLoadProgress = function(
			target:MovieClip,
			bl:Number,
			bt:Number
		):Void {
			var mc:MovieClip = target._parent;
			var p:Number = ((bt > 0) ? bl / bt * 100 : 0) >> 0;
			// Show percentages in the loader textfield.
			this.loader.setValue(p);
		};
		mclListener.onLoadInit = function(target:MovieClip):Void {
			var mc:MovieClip = target._parent;
			// Stops the loader animation.
			this.loader.removeAnimation();
			// Fade in picture.
			mc.pic._visible = true;
			mc.pic._alpha = 0;
			mc.pic.onEnterFrame = function():Void {
				if((this._alpha += 10) > 90) {
					this._alpha = 100;
					this._parent.loader._visible = false;
					delete this.onEnterFrame;
				}
			};
			// Fix size.
			var sze:Number = (mc.isThumb) ? 42 : 280; // "small" : "huge"
			if(mc.pic._width != sze || mc.pic._height != sze) {
				mc.pic._width = sze;
				mc.pic._height = sze;
			}
		};
		// Create loader an attach listener object.
		var mcLoader:MovieClipLoader = new MovieClipLoader();
		mcLoader.addListener(mclListener);
		// Store size info to identify container as thumb or full view.
		clip.isThumb = (clip._width < 64);
		// Start loading.
		mclListener.loader.createAnimation();
		mcLoader.loadClip(url, clip.pic);
	}

	/*
	 * Transforms the gross.
	 * i.e. converts Number(16.9) to String("16,90")
	 */
	private static function transformGross(nGross:Number):String {
		var a:String = Math.round(nGross * 100).toString();
		return a.substring(0, a.length-2 ) + "," + a.substr(-2);
	}

}
